package com.sudoku.board;

import java.util.ArrayList;
import java.util.Arrays;

import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Vector2;
import com.sudoku.observer.Subject;
import com.sudoku.utility.Constants;
import com.sudoku.utility.Locator;

public class Box implements Constants {

	private Vector2 coords;
	/*
	 * data has tiles in order as shown below 0 3 6 1 4 7 2 5 8
	 */
	private ArrayList<Tile> data;

	private Subject subject;

	public Box(Vector2 c, boolean random, Subject subject) {
		coords = c;
		this.subject = subject;
		data = new ArrayList<Tile>();
		if (random) {
			shuffle();
		} else {
			// create box with empty tiles
			for (int i = 0; i < 3; i++) {
				for (int j = 2; j >= 0; j--) {
					data.add(new Tile(this, new Vector2(i, j), ' ', subject));
				}
			}
		}
	}

	// creates a random box of numbers
	public Box shuffle() {
		data.clear();
		ArrayList<Integer> values = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
		for (int i = 0; i < 3; i++) {
			for (int j = 2; j >= 0; j--) {
				int r = (int) (Math.random() * values.size());
				data.add(new Tile(this, new Vector2(i, j), String.valueOf(values.get(r)).charAt(0), subject));
				values.remove(r);
			}
		}
		return this;
	}

	public ArrayList<Tile> getTilesInBoxRow(int num) {
		ArrayList<Tile> row = new ArrayList<Tile>();
		row.add(data.get(num));
		row.add(data.get(num + 3));
		row.add(data.get(num + 6));
		return row;
	}

	public ArrayList<Tile> getTilesInBoxCol(int num) {
		ArrayList<Tile> col = new ArrayList<Tile>();
		col.add(data.get(num * 3));
		col.add(data.get(num * 3 + 1));
		col.add(data.get(num * 3 + 2));
		return col;
	}

	public ArrayList<Integer> getBoxRow(int num) {
		ArrayList<Integer> row = new ArrayList<Integer>();

		char tileData = data.get(num).getData();
		if (Character.isDigit(tileData)) {
			row.add(Board.CharToInt(tileData));
		}

		tileData = data.get(num + 3).getData();
		if (Character.isDigit(tileData)) {
			row.add(Board.CharToInt(tileData));
		}

		tileData = data.get(num + 6).getData();
		if (Character.isDigit(tileData)) {
			row.add(Board.CharToInt(tileData));
		}
		return row;
	}

	public ArrayList<Integer> getBoxCol(int num) {
		ArrayList<Integer> col = new ArrayList<Integer>();

		char tileData = data.get(num * 3).getData();
		if (Character.isDigit(tileData)) {
			col.add(Board.CharToInt(tileData));
		}

		tileData = data.get(num * 3 + 1).getData();
		if (Character.isDigit(tileData)) {
			col.add(Board.CharToInt(tileData));
		}

		tileData = data.get(num * 3 + 2).getData();
		if (Character.isDigit(tileData)) {
			col.add(Board.CharToInt(tileData));
		}
		return col;
	}

	public Vector2 getCoords() {
		return coords;
	}

	public void setCoords(Vector2 coords) {
		this.coords = coords;
	}

	public float getXPosition() {
		return BOARD_START_POSITION + coords.x * BOX_PIXEL_SIZE;
	}

	public float getYPosition() {
		return coords.y * BOX_PIXEL_SIZE;
	}

	public float getXViewPosition() {
		return Locator.getViewport().getLeftGutterWidth() + Locator.BOARD_START_POSITION + coords.x * Locator.BOX_PIXEL_SIZE;
	}

	public float getYViewPosition() {
		return coords.y * Locator.BOX_PIXEL_SIZE;
	}

	public void drawTiles(SpriteBatch sb, BitmapFont font, BitmapFont pencilFont, ShapeRenderer sr) {
		for (Tile t : data) {
			t.render(sb, font, pencilFont, sr);
		}
	}

	public ArrayList<Tile> getData() {
		return data;
	}

	public ArrayList<Integer> getNumbers() {
		ArrayList<Integer> numbers = new ArrayList<Integer>();
		for (Tile t : data) {
			if (Character.isDigit(t.getData())) {
				numbers.add(Board.CharToInt(t.getData()));
			}
		}
		return numbers;
	}

	public void setData(ArrayList<Tile> data) {
		this.data = data;
	}

	public void setTile(int position, Tile t) {
		data.set(position, t);
	}

}
